package com.xiaoxiong.text;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

/**
 * 
 * @ClassName: LoginServer 
 * @Description: 模拟登录
 * @author xiaoxiong
 * @date 2016年5月4日 上午12:00:03 
 *
 */
public class LoginServer {
	/**
	 * 上下文
	 */
	private Context activity;
	/**
	 * 网络请求
	 */
	private StringHttp stringHttp;
	/**
	 * 消息
	 */
	private Handler handler;
	/**
	 * 用户名
	 */
	private String username;
	/**
	 * 密码
	 */
	private String password;
	/**
	 * 请求的地址
	 */
	private String url;

	/**
	 * 华软内网需要获取这个数据
	 */
	private String dataKey = "";
	private String data = "";
	/**
	 * 华软内网需要获取这个隐藏域
	 */
	private static boolean isGetHidden = false;
	// 
	/**
	 * 登录，还有后面获取的其他信息都需要的cookie
	 */
	private String cookie;
	/**
	 * 是否登录成功的标记
	 */
	private static boolean isLogin = false;
	/**
	 * 存储数据
	 */
	private SharedPreferences nb_message;

	/**
	 * 构造函数，要传入以下内容
	 * @param activity
	 * @param handler
	 * @param nb_message
	 * @param username
	 * @param password
	 */
	public LoginServer(Context activity, Handler handler,
			SharedPreferences nb_message, String username, String password) {
		super();
		this.activity = activity;
		this.stringHttp = new StringHttp(activity);
		this.handler = handler;
		this.username = username;
		this.password = password;
		this.nb_message = nb_message;
		//默认没有获取隐藏域
		this.isGetHidden = false;
	}

	/**
	 * 
	* @Title: doLogin 
	* @Description: 开始模拟登录
	* @param 
	* @return void
	* @throws
	 */
	public void doLogin() {
		//获取地址
		url = SchoolUrl.LoginUrl;
		//发送Post请求
		Post(activity, url, postHandler);
	}

	/**
	 * 处理请求返回来的信息
	 */
	public Handler postHandler = new Handler() {
		public void handleMessage(Message msg) {
			super.handleMessage(msg);

			Bundle bundle = msg.getData();
			//请求得到的内容
			String response = bundle.getString("Value");
			//是否请求成功
			isLogin = bundle.getBoolean("isSuccess");
			
			if (isLogin) {
				//如果没获取隐藏域，先获取
				if (!isGetHidden) {
					// Log.d("hidden", "yes");
					isGetHidden = true;
					//处理请求返回来的内容，获取隐藏域
					DealData(response);
					//获取登录地址
					url = SchoolUrl.LoginCheckUrl;
					//再次发送请求登录
					Post(activity, url, postHandler);
				} else {
					// Log.d("response", response);
					//判断是否登录成功
					boolean isTrue = judge(response);

					
					if (isTrue) {
						getCookie();
						Map<String, String> postDatas = new HashMap<String, String>();
						// Log.d("cookies", cookie);
						postDatas.put("JSESSIONID", cookie);
						// 获取各个网址
						url = SchoolUrl.SelectClassUrl;
						//发送请求
						stringHttp.Post(url, HadPostHandler, postDatas);
					}
				}
			} else {
				
				sendErrorMessage("请求失败，请检测你的网络1");
			}

		};
	};

	/**
	 * 获取各个网址后返回的数据
	 */
	@SuppressLint("HandlerLeak")
	public Handler HadPostHandler = new Handler() {
		public void handleMessage(Message msg) {
			super.handleMessage(msg);

			Bundle bundle = msg.getData();
			String response = bundle.getString("Value");
			isLogin = bundle.getBoolean("isSuccess");
			
			if (isLogin) {

				// 处理返回的数据，获取各个地址
				new GetAllLoad(activity, response);
				//保存用户信息
				setUserInfo();
				//发送登录并获取其他信息的地址成功
				sendSuccessMessage(response);
			} else {
				sendErrorMessage("请求失败，请检测你的网络2");
			}

		};
	};

	/**
	 * 
	* @Title: getCookie 
	* @Description: 获取cookies
	* @param 
	* @return void
	* @throws
	 */
	private void getCookie() {
		cookie = nb_message.getString("logincookie", null);
		// 由于取出cookie是包含KEY的，所以要去掉
		StringBuilder sb = new StringBuilder(cookie);
		sb.delete(sb.indexOf(";"), sb.length());
		sb.delete(0, sb.indexOf("=") + 1);
		cookie = sb.toString();
	}

	/**
	 * 
	* @Title: DealData 
	* @Description: 获取隐藏域
	* @param @param response
	* @return void
	* @throws
	 */
	private void DealData(String response) {
		//服务器返回的是整个html页面代码，我们处理成String类型了，所以这里要用到Jsoup封装成Document类型
		Document content = Jsoup.parse(response);
		//根据form表单解析
		Elements element = content.getElementsByTag("form");
		//获取表单中第一个节点的name值
		dataKey = element.get(0).childNode(1).attr("name");
		//获取表单中第一个节点的value值
		data = element.get(0).childNode(1).attr("value");
	}

	/**
	 * 
	* @Title: Matching 
	* @Description: 用正则匹配内容
	* @param @param str
	* @param @return
	* @return boolean
	* @throws
	 */
	private boolean Matching(String str) {

		//如果含有sise/index.jsp，说明登录成功
		Matcher m1 = Pattern.compile("sise/index.jsp").matcher(str);

		if (m1.find()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 
	* @Title: judge 
	* @Description: 判断是否登录成功
	* @param @param response 网页内容
	* @param @return
	* @return boolean
	* @throws
	 */
	private boolean judge(String response) {
		//用正则匹配
		if (Matching(response)) {

			return true;

		} else {
			sendErrorMessage("学号或密码错误");

			return false;
		}
	}

	/**
	 * 
	* @Title: Post 
	* @Description: 提交post请求
	* @param @param context 提交所属的context
	* @param @param Url 提交的网址
	* @param @param handler 返回信息时接收的handler
	* @return void
	* @throws
	 */
	private void Post(Context context, String Url, Handler handler) {

		//保存参数的map
		Map<String, String> postDatas = new HashMap<String, String>();
		//如果已经获取隐藏域，说明这次请求是要模拟登录，需要传参数
		if (isGetHidden) {
			//传入隐藏域、用户名、密码
			postDatas.put(dataKey, data);
			postDatas.put("username", username);
			postDatas.put("password", password);
			// Log.d("key", dataKey + "=" + data);

			//发送请求
			stringHttp.Post(url, handler, postDatas, nb_message, "logincookie");
		} else {
			// Log.d("key", "---------------------");
			//发送请求，这个不带参数，只是先进入index页面获取隐藏域
			stringHttp.Post(url, handler, postDatas);
		}
	}

	/**
	 * 
	* @Title: setUserInfo 
	* @Description: 保存用户数据
	* @param 
	* @return void
	* @throws
	 */
	private void setUserInfo() {
		Editor editor = nb_message.edit();
		editor.putString("username", username);
		editor.putString("username", password);
		editor.commit();
	}

	/**
	 * 
	* @Title: sendErrorMessage 
	* @Description: 请求失败时调用
	* @param @param error 失败的信息
	* @return void
	* @throws
	 */
	private void sendErrorMessage(String error) {

		Message msg = new Message();
		Bundle bundle = new Bundle();
		bundle.putString("Value", error);
		bundle.putBoolean("isSuccess", false);
		msg.setData(bundle);

		handler.sendMessage(msg);
	}

	/**
	 * 
	* @Title: sendSuccessMessage 
	* @Description: 请求成功时调用
	* @param @param success 请求成功，服务器放回的html页面
	* @return void
	* @throws
	 */
	private void sendSuccessMessage(String success) {

		Message msg = new Message();
		Bundle bundle = new Bundle();
		bundle.putString("Value", success);
		bundle.putBoolean("isSuccess", true);
		msg.setData(bundle);

		handler.sendMessage(msg);
	}

}
